{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SageMaker Pipelines to Train a BERT-Based Text Classifier\n",
    "\n",
    "In this lab, we will do the following:\n",
    "* Define a set of Workflow Parameters that can be used to parametrize a Workflow Pipeline\n",
    "* Define a Processing step that performs cleaning and feature engineering, splitting the input data into train and test data sets\n",
    "* Define a Training step that trains a model on the pre-processed train data set\n",
    "* Define a Processing step that evaluates the trained model's performance on the test data set\n",
    "* Define a Register Model step that creates a model package from the estimator and model artifacts used in training\n",
    "* Define a Conditional step that measures a condition based on output from prior steps and conditionally executes the Register Model step\n",
    "* Define and create a Pipeline in a Workflow DAG, with the defined parameters and steps defined\n",
    "* Start a Pipeline execution and wait for execution to complete"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Terminology\n",
    "\n",
    "Amazon SageMaker Pipelines support the following steps:\n",
    "\n",
    "* Pipelines - A Directed Acyclic Graph of steps and conditions to orchestrate SageMaker jobs and resource creation.\n",
    "* Processing Job steps - A simplified, managed experience on SageMaker to run data processing workloads, such as feature engineering, data validation, model evaluation, and model interpretation.\n",
    "* Training Job steps - An iterative process that teaches a model to make predictions by presenting examples from a training dataset.\n",
    "* Conditional step execution - Provides conditional execution of branches in a pipeline.\n",
    "* Registering Models - Creates a model package resource in the Model Registry that can be used to create deployable models in Amazon SageMaker.\n",
    "* Parametrized Pipeline executions - Allows pipeline executions to vary by supplied parameters.\n",
    "* Transform Job steps - A batch transform to preprocess datasets to remove noise or bias that interferes with training or inference from your dataset, get inferences from large datasets, and run inference when you don't need a persistent endpoint."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Our BERT Pipeline\n",
    "\n",
    "In the Processing Step, we perform Feature Engineering to create BERT embeddings from the `review_body` text using the pre-trained BERT model, and split the dataset into train, validation and test files. To optimize for Tensorflow training, we saved the files in TFRecord format. \n",
    "\n",
    "In the Training Step, we fine-tune the BERT model to our Customer Reviews Dataset and add a new classification layer to predict the `star_rating` for a given `review_body`.\n",
    "\n",
    "In the Evaluation Step, we take the trained model and a test dataset as input, and produce a JSON file containing classification evaluation metrics.\n",
    "\n",
    "In the Condition Step, we decide whether to register this model if the accuracy of the model, as determined by our evaluation step exceeded some value. \n",
    "\n",
    "![](./img/bert_sagemaker_pipeline.png)\n",
    "\n",
    "The pipeline that we create follows a typical Machine Learning Application pattern of pre-processing, training, evaluation, and model registration:\n",
    "\n",
    "![A typical ML Application pipeline](img/pipeline-full.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Release Resources"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%html\n",
    "\n",
    "<p><b>Shutting down your kernel for this notebook to release resources.</b></p>\n",
    "<button class=\"sm-command-button\" data-commandlinker-command=\"kernelmenu:shutdown\" style=\"display:none;\">Shutdown Kernel</button>\n",
    "\n",
    "<script>\n",
    "try {\n",
    "    els = document.getElementsByClassName(\"sm-command-button\");\n",
    "    els[0].click();\n",
    "}\n",
    "catch(err) {\n",
    "    // NoOp\n",
    "}    \n",
    "</script>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%javascript\n",
    "\n",
    "try {\n",
    "    Jupyter.notebook.save_checkpoint();\n",
    "    Jupyter.notebook.session.delete();\n",
    "}\n",
    "catch(err) {\n",
    "    // NoOp\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "instance_type": "ml.t3.medium",
  "kernelspec": {
   "display_name": "Python 3 (Data Science)",
   "language": "python",
   "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
